// Albireo.Base32.Base32
using System;
using System.Linq;

namespace APP
{
	public static class Base32
	{
		private const byte BitsInBlock = 5;

		private const byte BitsInByte = 8;

		private const string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";

		private const char Padding = '=';

		public static string Encode(in byte[] input)
		{
			if (input == null)
			{
				throw new ArgumentNullException("input");
			}
			if (input.Length == 0)
			{
				return string.Empty;
			}
			checked
			{
				char[] array = new char[(int)decimal.Ceiling((decimal)input.Length / 5m) * 8];
				int num = 0;
				byte b = 0;
				byte b2 = 5;
				byte[] array2 = input;
				foreach (byte b3 in array2)
				{
					b = (byte)(b | (b3 >> 8 - unchecked((int)b2)));
					array[num++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"[b];
					if (b2 < 3)
					{
						b = (byte)((b3 >> 3 - unchecked((int)b2)) & 0x1F);
						array[num++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"[b];
						b2 = (byte)(unchecked((int)b2) + 5);
					}
					b2 = (byte)(unchecked((int)b2) - 3);
					b = (byte)((b3 << unchecked((int)b2)) & 0x1F);
				}
				if (num != array.Length)
				{
					array[num++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"[b];
				}
				while (num < array.Length)
				{
					array[num++] = '=';
				}
				return new string(array);
			}
		}

		public static byte[] Decode(in string input)
		{
			if (input == null)
			{
				throw new ArgumentNullException("input");
			}
			if (string.IsNullOrEmpty(input))
			{
				return new byte[0];
			}
			char[] array = input.TrimEnd(new char[1]
			{
			'='
			}).ToUpperInvariant().ToCharArray();
			if (array.Any((char x) => "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".IndexOf(x) == -1))
			{
				throw new ArgumentException("input");
			}
			byte[] array2 = new byte[checked(array.Length * 5) / 8];
			int num = 0;
			byte b = 0;
			byte b2 = 8;
			char[] array3 = array;
			checked
			{
				foreach (char value in array3)
				{
					int num2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".IndexOf(value);
					if (b2 > 5)
					{
						int num3 = num2 << unchecked((int)b2) - 5;
						b = (byte)(b | num3);
						b2 = (byte)(unchecked((int)b2) - 5);
					}
					else
					{
						int num3 = num2 >> 5 - unchecked((int)b2);
						b = (byte)(b | num3);
						array2[num++] = b;
						b = unchecked((byte)(num2 << 3 + b2));
						b2 = (byte)(unchecked((int)b2) + 3);
					}
				}
				return array2;
			}
		}
	}

}
